package com.caishi.lkx.order.api;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.caishi.lkx.common.BaseApi;
import com.caishi.lkx.exam.ienum.type.ColumnType;
import com.caishi.lkx.exam.ienum.type.PackageTagType;
import com.caishi.lkx.exam.model.*;
import com.caishi.lkx.exam.records.RecordsGetDataService;
import com.caishi.lkx.exam.records.dto.RecordsCountRecordDto;
import com.caishi.lkx.exam.service.*;
import com.caishi.lkx.order.vo.MyCategoryVO;
import com.zzw.common.Wrappers;

import com.caishi.lkx.order.config.AssetsRouter;
import com.caishi.lkx.order.ienum.status.AssetsStatus;
import com.caishi.lkx.order.ienum.type.AssetsType;
import com.caishi.lkx.order.model.UserAssetsDataModel;
import com.caishi.lkx.order.service.IUserAssetsDataService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;


@Tag(name = "我的资源相关接口")
@RestController
@RequestMapping("/order/user-assets")
public class UserAssetsApi extends BaseApi {

    @Resource
    private IUserAssetsDataService userAssetsDataService;
    @Resource
    private ICategoryService categoryService;
    @Resource
    private IExamService examService;
    @Resource
    private IIndustryService industryService;
    @Resource
    private IPackageSkuService packageSkuService;
    @Resource
    private IColumnService columnService;
    @Resource
    private IProductBaseService productBaseService;
    @Resource
    private IPackageService packageService;

    @Resource
    private RecordsGetDataService recordsGetDataService;

    @GetMapping("/user-have")
    public IPage<UserAssetsDataModel> userAssets(
            @ModelAttribute Page<UserAssetsDataModel> page,
            String userId,
            AssetsType assetType,
            String assetMappingId,
            AssetsStatus status,
            LocalDateTime startTime,
            LocalDateTime endTime
    ) {
        IPage<UserAssetsDataModel> data = userAssetsDataService.page(page, Wrappers.<UserAssetsDataModel>lambdaQuery()
                .eq(UserAssetsDataModel::getUserId, StrUtil.isBlank(userId) ? userContext.currentUserId() : userId)
                .eq(assetType != null, UserAssetsDataModel::getAssetType, assetType)
                .eq(status != null, UserAssetsDataModel::getStatus, status)
                .gt(startTime != null, UserAssetsDataModel::getStartTime, startTime)
                .le(endTime != null, UserAssetsDataModel::getEndTime, endTime)
                .eq(StrUtil.isNotBlank(assetMappingId), UserAssetsDataModel::getAssetMappingId, assetMappingId)
        );
        return data.setRecords(data.getRecords().parallelStream()
                .peek(v -> v.setAssets(AssetsRouter.router.router(v.getAssetType()).assetsDetail(v.getAssetMappingId()))).filter(f -> f.getAssets() != null).toList());
    }

    @Operation(summary = "我的题库")
    @GetMapping("/my-subject-bank")
    public IPage<PackageSkuModel> mySubjectBank(@ModelAttribute Page<PackageSkuModel> page, @RequestParam(required = false, defaultValue = "false") boolean flag) {
        IPage<PackageSkuModel> resPage = new Page<>();
        //查询用户购买的产品
        List<UserAssetsDataModel> userAssetsDataModels = userAssetsDataService.selectList(Wrappers.<UserAssetsDataModel>lambdaQuery()
                .eq(UserAssetsDataModel::getUserId, userContext.currentUserId()).eq(UserAssetsDataModel::getAssetType, AssetsType.product).orderByDesc(UserAssetsDataModel::getStatus));
        HashMap<String, UserAssetsDataModel> columnAssetMap = new HashMap<>();
        HashMap<String, AssetsStatus> assetsStatus = new HashMap<>();
        List<String> packageSkuIds = new ArrayList<>();
        for (UserAssetsDataModel assetsDataModel : userAssetsDataModels) {
            columnAssetMap.put(assetsDataModel.getAssetMappingId(), assetsDataModel);
            packageSkuIds.add(assetsDataModel.getAssetMappingId());
            assetsStatus.put(assetsDataModel.getAssetMappingId(), assetsDataModel.getStatus());
        }
        if (CollUtil.isEmpty(packageSkuIds)) {
            return resPage;
        }
        List<PackageSkuModel> packageSkuModels = packageSkuService.selectBatchIds(packageSkuIds).parallelStream().peek(c -> {
            c.setIndustryName(industryService.queryName(c.getIndustryId()));
            c.setExamName(examService.queryName(c.getExamId()));
            if (!c.getCategoryIds().isEmpty()) {
                List<CategoryModel> categoryModels = categoryService.selectBatchIds(c.getCategoryIds()).parallelStream().peek(model -> {
                    List<ColumnModel> columnModels = columnService.selectList(Wrappers.<ColumnModel>lambdaQuery().ne(null != c.getIndustryId() && c.getIndustryId().equals("gjtk"), ColumnModel::getType, ColumnType.randomFormPaper).eq(ColumnModel::getCategoryId, model.getId()));
                    Map<String, ColumnModel> collect = columnModels.parallelStream().collect(Collectors.toMap(v -> v.getType().getDesc(), v -> v, (v, v1) -> v));
                    model.setColumns(new ArrayList<>(collect.values()));
                }).toList();
                c.setCategoryList(categoryModels);
            }
            UserAssetsDataModel userAssetsDataModel = columnAssetMap.get(c.getId());
            c.setStartTime(userAssetsDataModel.getStartTime());
            PackageModel packageModel = packageService.getById(c.getPackageId());
            if (packageModel.getEndDate() == null) {
                long days = packageModel.getDays().longValue();
                LocalDateTime endTime = userAssetsDataModel.getStartTime().plusDays(days);
                c.setEndTime(endTime);
            } else {
                c.setEndTime(userAssetsDataModel.getEndTime());
            }
        }).toList();
        List<PackageSkuModel> recordVos = new ArrayList<>();
        int currIdx = (int) (page.getCurrent() > 1 ? (page.getCurrent() - 1) * page.getSize() : 0);
        for (int i = 0; i < page.getSize() && i < packageSkuModels.size() - currIdx; i++) {
            PackageSkuModel packageSkuModel = packageSkuModels.get(currIdx + i);
            packageSkuModel.setEfficient(assetsStatus.get(packageSkuModel.getId()));
            recordVos.add(packageSkuModel);
        }
        resPage.setRecords(recordVos.stream().sorted((s1, s2) -> {
            if (s1.getEfficient().equals(AssetsStatus.effective) && (s2.getEfficient().equals(AssetsStatus.overdue) || s2.getEfficient().equals(AssetsStatus.invalid))) {
                return -1;
            } else if (s1.getEfficient().equals(s2.getEfficient())) {
                return s1.getEndTime().compareTo(s2.getEndTime());
            }
            return 1;
        }).toList());
        resPage.setTotal(packageSkuModels.size());
        resPage.setSize(page.getSize());
        resPage.setPages(page.getPages());
        resPage.setCurrent(page.getCurrent());
        return resPage;
    }

    @Operation(summary = "我购买的考试")
    @GetMapping("/my-buy-exam")
    public List<ExamModel> myBuyExam(){

        if(StrUtil.isBlank(userContext.currentUserId()))
            return new ArrayList<>();
        //查询用户购买的科目
        List<UserAssetsDataModel> userAssetsDataModels = userAssetsDataService.selectList(Wrappers.<UserAssetsDataModel>lambdaQuery()
                .eq(UserAssetsDataModel::getUserId, userContext.currentUserId()).eq(UserAssetsDataModel::getAssetType, AssetsType.category).eq(UserAssetsDataModel::getDeleted, false).orderByDesc(UserAssetsDataModel::getStatus));
       if(userAssetsDataModels.isEmpty())
           return new ArrayList<>();

        //查询考试ids
        List<CategoryModel> categoryList = categoryService.selectList(Wrappers.<CategoryModel>lambdaQuery().in(CategoryModel::getId, userAssetsDataModels.stream().map(UserAssetsDataModel::getAssetMappingId).toList()));
        var examIdArray = categoryList.stream().map(CategoryModel::getExamId).toList();
        var examList = examService.selectList(Wrappers.<ExamModel>lambdaQuery().in(ExamModel::getId, examIdArray));
        //转载考试下面的已购科目
        examList.forEach(c ->c.setCategorys(categoryList.stream().filter(v -> v.getExamId().equals(c.getId())).toList()));
        return examList;
    }
    List<ColumnType> checkColumnType(PackageTagType type){
        List<ColumnType> columnTypes;
        //判断资料，课程，题库,直播，查询对应栏目
        if(type == PackageTagType.question){
            columnTypes = Arrays.asList(ColumnType.randomFormPaper, ColumnType.paperLibrary, ColumnType.chapterPractice,ColumnType.specialPractice);
        }else {
            if (type == PackageTagType.video){
                columnTypes = List.of(ColumnType.video);
            }else if(type == PackageTagType.material){
                columnTypes = List.of(ColumnType.materialInfo);
            }else{
                columnTypes = List.of(ColumnType.live);
            }
        }
        return columnTypes;
    }
    @Operation(summary = "我购买的资源")
    @GetMapping("/my-buy-asset")
    public List<MyCategoryVO> myBuyAsset(@RequestParam PackageTagType type, @RequestParam String categoryIds){
        var columnTypes = checkColumnType(type);
        List<MyCategoryVO> myCategoryVOS = new ArrayList<>();
        Arrays.stream(categoryIds.split(","))
                .map(String::trim)
                .toList().forEach(v -> {
                        //对应科目查询栏目，因为要进行科目以及订单分组，所以只能一个科目循环查询
                        List<ColumnModel> columnModels =  columnService.selectList(Wrappers.<ColumnModel>lambdaQuery().eq(ColumnModel::getCategoryId, v).in( ColumnModel::getType, columnTypes));

                        List<String> columnIdArray= columnModels.stream().map(ColumnModel::getId).toList();
                        if(!columnIdArray.isEmpty()){
                            //查询栏目资产
                            var columnAssets = userAssetsDataService.selectList(Wrappers.<UserAssetsDataModel>lambdaQuery().eq(UserAssetsDataModel::getUserId, userContext.currentUserId()).eq(UserAssetsDataModel::getAssetType, AssetsType.column).in(UserAssetsDataModel::getAssetMappingId, columnIdArray));
                            //通过订单进行栏目分组
                            var columnAssetMap = columnAssets.stream()
                                    .collect(Collectors.groupingBy(UserAssetsDataModel::getLastOrderId));
                            var categoryModel = categoryService.getById(Long.valueOf(v));
                            //装载数据
                            columnAssetMap.forEach((k, assets) -> {
                                myCategoryVOS.add(MyCategoryVO.builder().categoryName(categoryModel.getName()).categoryId(categoryModel.getId()).efficientStatus(assets.get(0).getStatus()).efficientTime(assets.get(0).getEndTime()).columnModels(columnModels.stream().filter(c -> assets.stream().anyMatch(a -> a.getAssetMappingId().equals(c.getId()))).toList()).build());
                            });
                        }

                    });

        return myCategoryVOS;
    }
    @Operation(summary = "我的题库(mobile)")
    @GetMapping("/my-subject")
    public List<CategoryModel> subject() {
        //获取用户资产下面有效的科目
        List<UserAssetsDataModel> userAssetsDataModels = userAssetsDataService.selectList(Wrappers.<UserAssetsDataModel>lambdaQuery()
                .eq(UserAssetsDataModel::getUserId, userContext.currentUserId())
                .eq(UserAssetsDataModel::getAssetType, AssetsType.category)
                .select(UserAssetsDataModel::getAssetMappingId)
        );
        List<Long> userCategoryId = userAssetsDataModels.parallelStream().map(m -> {
            String assetMappingId = m.getAssetMappingId();
            return Long.parseLong(assetMappingId);
        }).toList();
        String currentUserId = userContext.currentUserId();
        List<CategoryModel> categoryModelList = categoryService.selectBatchIds(userCategoryId);
        return categoryModelList.parallelStream().peek(e -> {
            RecordsCountRecordDto categoryCountRecordsResult = recordsGetDataService.getCategoryCountRecordsResult(currentUserId, e.getIndustryId(), e.getExamId(), e.getId());
            e.setExamName(examService.queryName(e.getExamId()));
            e.setCategoryRecords(categoryCountRecordsResult);
        }).toList();

    }
}
